<style scoped>
.photo-wall {
  width: 100%;
  height: 100%;
}
.show_info {
  position: fixed;
  background-color: rgba(0, 0, 0, 0.6);
  padding: 10px;
  width: 500px;
  margin: 0 auto;
  left: 0;
  right: 0;
  border-radius: 20px;
  display: flex;
  padding: 40px 30px;
  
  top: 40%;
}
.show_man{
  box-shadow: 0px 0px 10px 5px #01c1ee;
}
.show_woman{

 box-shadow: 0px 0px 10px 5px #ffbd51;
}
.show_info img {
  display: block;
  margin: auto;
  border-radius: 15px;
  box-shadow: 0 0 10px 0 #888;
  margin-right: 40px;
}

.show_info .info_my {
  text-align: center;
}
.show_info .info_my img{
  border: 3px solid #01c1ee
}
.show_info .info_my > * {
  display: inline-block !important;
  vertical-align: middle;
}
.nickname{
    font-size: 50px;
    font-weight: bold;
    color: #fff;
}
.intro {
  color: #fff;
  /* text-indent: 20px; */
  margin-top: 10px;
  height: 70px;
  overflow: hidden;
  font-size: 26px;
  /* white-space: nowrap */
  /* display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical; */
}

</style>
<style>
.photo-wall .element {
  box-sizing: border-box;
}
.photo-wall .element img {
  max-width: 120px;
  max-height: 120px;
  box-sizing: border-box;
}
.photo-wall .element.new img {
}
.man{
  border:3px solid #01c1ee!important;
  border-radius: 10px
}
.woman{
  border:3px solid #ffbd51!important;
   border-radius: 10px
}
</style>

<template>
  <div>
    <div class="photo-wall" ref="wall">
    </div>
    <div class="show_info animated" :class="sex==2?'show_man':'show_woman'" style="display:none;" ref="show_info">
      <div class="info_my">
        <img :class="sex==2?'man':'woman'" style="width:120px;height:120px" :src="headURL" />
      </div>
      <div>
        <div class="nickname">{{name}}</div>
        <div class="intro">{{company}}</div>
      </div>
    </div>
  </div>

</template>

<script>
export default {
  data() {
    return {
      showInfo: false,
      name:'',
      company:'',
      headURL:'',
      sex:null
    };
  },
  props: {
    list: Array,
    newPerson: Object
  },
  watch: {
    list: function(value) {
      if (this.$refs.wall) {
        this.init(this.$refs.wall, this.list);
      }
    },
    newPerson: function(value) {
      if (value) {
        if (this.insertPerson) {
          this.insertPerson(value);
        }
      }
    }
  },
  mounted() {
    if (this.list) {
      this.init(this.$refs.wall, this.list);
    }
  },
  beforeDestroy() {
    if (this.onDestroy) {
      this.onDestroy();
    }
  },
  methods: {
    init(container, personArray) {
      // let arr = personArray;
      // personArray = [];
      // for (let i = 0; i < 300; i++) {
      //   const o = Object.assign({}, arr[Math.floor(arr.length * Math.random())]);
      //   o.user_id = Math.random();
      //   personArray.push(o);
      // }
      // console.log(personArray);
      let _this = this
      container.innerHTML = "";
      if (this.onDestroy) {
        this.onDestroy();
      }

      const MAX_PERSON = 400;
      let isDestroy = false;
      let personMap = {};
      let personList = [];
      let personQueue = [];

      let CurPersonNum = 0;
      let animateTimerId = 0;
      // 自动更换
      let animateType = 0;
      // animate
      let _in = [
        "bounceIn",
        "bounceInDown",
        "bounceInLeft",
        "bounceInRight",
        "bounceInUp",
        "fadeIn",
        "fadeInDown",
        "fadeInDownBig",
        "fadeInLeft",
        "fadeInLeftBig",
        "fadeInRight",
        "fadeInRightBig",
        "fadeInUp",
        "fadeInUpBig",
        "rotateIn",
        "rotateInDownLeft",
        "rotateInDownRight",
        "rotateInUpLeft",
        "rotateInUpRight",
        "slideInDown",
        "slideInLeft",
        "slideInRight"
      ];
      let _out = [
        "bounceOut",
        "bounceOutDown",
        "bounceOutLeft",
        "bounceOutRight",
        "bounceOutUp",
        "fadeOut",
        "fadeOutDown",
        "fadeOutDownBig",
        "fadeOutLeft",
        "fadeOutLeftBig",
        "fadeOutRight",
        "fadeOutRightBig",
        "fadeOutUp",
        "fadeOutUpBig",
        "rotateOut",
        "rotateOutDownLeft",
        "rotateOutDownRight",
        "rotateOutUpLeft",
        "rotateOutUpRight",
        "slideOutDown",
        "slideOutLeft",
        "slideOutRight"
      ];
      let THREE = window.THREE;
      let TWEEN = window.TWEEN;

      let maxColumn = 20;
      let camera, scene, renderer;
      let controls;

      let objects = [];
      let targets = { table: [], sphere: [], helix: [], grid: [] };

      let lastTime = 0;
    
      // 模拟推送数据
      // let mockInsertTimer = setInterval(showinfo,4500);
      function showinfo(){
        let person = personQueue[0];
        _this.sex = person.sex
        _this.name = person.name
        _this.company = person.company
        _this.headURL = person.head
        let ele = $(_this.$refs.show_info)
				// get animate
				let rand_in = parseInt(Math.random() * _in.length,10);
    		let rand_out = parseInt(Math.random() * _out.length,10);
				ele.show();
				ele.addClass(_in[rand_in]);
				setTimeout(function(f){
					ele.removeClass(_in[rand_in]);
					setTimeout(function(f){
						ele.addClass(_out[rand_out]);
						setTimeout(function(f){
							ele.removeClass(_out[rand_out]);
              ele.hide();
              personQueue.shift();
              if (personQueue.length) {
                f();
              }
						},1000, f);
					},1500, f);
				},1000, showinfo);
			}
      function insertPerson(person) {
        person = Object.assign({}, person);
        personQueue.push(person);
        if (personQueue.length === 1) {
          showinfo();
        }
        if (createPerson(person, "new")) {
          reset_sphere();
          reset_helix();
          reset_grid();
          transform_inc();
        }
      }

      function createPerson(person, className = "") {
        // console.log(person)
        let id = person.user_id || person.id;
        if (personMap[id] || personList.length >= MAX_PERSON) {
          return null;
        }
        personMap[id] = person;
        personList.push(person);
        let element = document.createElement("div");
        element.className = "element " + className;
        element.style.backgroundColor =
          "rgba(0,127,127," + (Math.random() * 0.5 + 0.25) + ")";

        let img = document.createElement("img");
        img.src = person.head;
        if(person.sex == 2){
          img.className = 'man'
        }else{
          img.className = 'woman'
        }
        element.appendChild(img);

        /*let number = document.createElement( 'div' );
				number.className = 'number';
				number.textContent = (i/5) + 1;
				element.appendChild( number );

				let symbol = document.createElement( 'div' );
				symbol.className = 'symbol';
				symbol.textContent = person;
				element.appendChild( symbol );

				let details = document.createElement( 'div' );
				details.className = 'details';
				details.innerHTML = table[ i + 1 ] + '<br>' + table[ i + 2 ];
				element.appendChild( details );*/

        let object = new THREE.CSS3DObject(element);
        // object.position.x = Math.random() * 4000 - 2000;
        // object.position.y = Math.random() * 4000 - 2000;
        // object.position.z = Math.random() * 4000 - 2000;
        scene.add(object);

        let i = objects.length;
        objects.push(object);

        person.p_x = (i % maxColumn) + 1;
        person.p_y = Math.floor(i / maxColumn) + 1;

        // 表格需要坐标进行排序的
        let object2 = new THREE.Object3D();
        // object2.position.x = ( table[ i + 3 ] * 140 ) - 1330;
        // object2.position.y = - ( table[ i + 4 ] * 180 ) + 990;
        object2.position.x = person.p_x * 140 - 1330;
        object2.position.y = -(person.p_y * 180) + 990;

        targets.table.push(object2);
        return object;
      }

      function reset_sphere() {
        // sphere
        let vector = new THREE.Vector3();
        let spherical = new THREE.Spherical();

        for (let i = 0, l = objects.length; i < l; i++) {
          let phi = Math.acos(-1 + (2 * i) / l);
          let theta = Math.sqrt(l * Math.PI) * phi;

          let object = targets.sphere[i];
          if (!object) {
            object = new THREE.Object3D();
            targets.sphere.push(object);
          }
          // spherical.set(800, phi, theta);
          spherical.set(window.innerHeight * 0.95, phi, theta);
          object.position.setFromSpherical(spherical);
          vector.copy(object.position).multiplyScalar(2);
          object.lookAt(vector);
        }
      }

      function reset_helix(scale = 1) {
        // helix
        let vector = new THREE.Vector3();
        let cylindrical = new THREE.Cylindrical();

        for (let i = 0, l = objects.length; i < l; i++) {
          // let theta = i * 0.175 + Math.PI;
          // let y = -(i * 5) + 450;
          // let y = -(i * 5) + l / 2 * 5;
          // scale = 2;
          let n = Math.PI / (120 * scale / 1000) - 2;
          let w = Math.PI / n;
          let theta = i * w + Math.PI;
          // scale = 1
          let y = -(i * 5) + l / 2 * 5;
          n = (120 * scale) / (n + 2);
          console.log(n)
          y = -(i * n) + l / 2 * n;
          y *= 0.7;
          // y = 0;

          let object = targets.helix[i];
          if (!object) {
            object = new THREE.Object3D();
            targets.helix.push(object);
          }

          // 参数一 圈的大小 参数二 左右间距 参数三 上下间距
          cylindrical.set(1000, theta, y);

          object.position.setFromCylindrical(cylindrical);

          vector.x = object.position.x * 2;
          vector.y = object.position.y;
          vector.z = object.position.z * 2;

          object.lookAt(vector);
        }
      }

      function reset_grid(scale = 1) {
        // grid
        for (let i = 0, l = objects.length; i < l; i++) {
          let object = targets.grid[i];
          if (!object) {
            object = new THREE.Object3D();
            targets.grid.push(object);
          }
          // object.position.x = (i % 5) * 400 - 800; // 400 图片的左右间距  800 x轴中心店
          // object.position.y = -(Math.floor(i / 5) % 5) * 300 + 500; // 500 y轴中心店
          // object.position.z = Math.floor(i / 25) * 200 - 800; // 300调整 片间距 800z轴中心店
          let h = window.innerHeight * 0.7;
          let n = Math.ceil(Math.pow(l, 1 / 3));
          object.position.x = (i % n) * 300 * scale - h; // 400 图片的左右间距  800 x轴中心店
          object.position.y = -(Math.floor(i / n) % n) * 200 * scale + h * 1 / scale; // 500 y轴中心店
          object.position.z = Math.floor(i / (n * n)) * 150 * scale - h; // 300调整 片间距 800z轴中心店
        }
      }

      personArray = personArray.slice(0, MAX_PERSON);
      let table = [];
      for (let i = 0; i < personArray.length; i++) {
        table[i] = {};
        if (i < personArray.length) {
          table[i] = personArray[i];
        }
        table[i].p_x = (i % 20) + 1;
        table[i].p_y = Math.floor(i / 20) + 1;
      }

      init();
      animate();

      function init() {
        camera = new THREE.PerspectiveCamera(
          40,
          window.innerWidth / window.innerHeight,
          1,
          10000
        );
        camera.position.z = 3000;

        scene = new THREE.Scene();

        // table

        for (let i = 0; i < table.length; i++) {
          let person = table[i];
          let object = createPerson(person);
          object.position.x = Math.random() * 4000 - 2000;
          object.position.y = Math.random() * 4000 - 2000;
          object.position.z = Math.random() * 4000 - 2000;
        }

        reset_sphere();
        reset_helix();
        reset_grid();

        //渲染
        renderer = new THREE.CSS3DRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        container.appendChild(renderer.domElement);

        // 鼠标控制
        controls = new THREE.TrackballControls(camera, renderer.domElement);
        controls.rotateSpeed = 0.5;
        controls.minDistance = 500;
        controls.maxDistance = 6000;
        controls.addEventListener("change", render);

        animateTimerId = setInterval(transform_ani, 8000);

        function transform_ani() {
          animateType = animateType >= 3 ? 0 : animateType;
          ++animateType;
          let scale = 1;
          let num = personList.length;
          switch (animateType) {
            case 1:
              if (num < 400) {
              	scale = 1 + 1 - num / 400;
              }
              transform(targets.sphere, 1000, scale);
              break;
            case 2:
              console.log(num);
              if (num < 300) {
              	scale = 1 + 1 - num / 300;
              }
              reset_helix(scale);
              transform(targets.helix, 1000, scale);
              break;
            case 3:
              if (num < 200) {
              	scale = 1 + 1 - num / 200;
              }
              reset_grid(scale);
              transform(targets.grid, 1000, scale);
              break;
          }
        }

        // transform(targets.table, 2000);
        animateType = 2;
        transform_ani();

        window.addEventListener("resize", onWindowResize, false);
      }

      function transform_inc() {
        let ani = targets.table;
        switch (animateType) {
          case 1:
            ani = targets.sphere;
            break;
          case 2:
            ani = targets.helix;
            break;
          case 3:
            ani = targets.grid;
            break;
        }
        transform(ani, 1000);
      }

      function transform(targets, duration, scale = 1) {
        TWEEN.removeAll();
        for (let i = 0; i < objects.length; i++) {
          let object = objects[i];
          let target = targets[i];

          // object.scale.x = object.scale.y = object.scale.z = scale;

          new TWEEN.Tween(object.scale)
            .to(
              {
                x: scale,
                y: scale,
                z: scale
              },
              Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();
          new TWEEN.Tween(object.position)
            .to(
              {
                x: target.position.x,
                y: target.position.y,
                z: target.position.z
              },
              Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();

          new TWEEN.Tween(object.rotation)
            .to(
              {
                x: target.rotation.x,
                y: target.rotation.y,
                z: target.rotation.z
              },
              Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();
        }

        new TWEEN.Tween({})
          .to({}, duration * 2)
          .onUpdate(render)
          .start();
      }

      function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
        render();
      }

      function animate() {
        if (isDestroy) {
          return;
        }

        // 让场景通过x轴或者y轴旋转  & z
        // scene.rotation.x += 0.011;
        scene.rotation.y += 0.008;

        requestAnimationFrame(animate);
        TWEEN.update();
        controls.update();
        // 渲染循环
        render();
      }

      function render() {
        renderer.render(scene, camera);
      }

      /** 将three.js三维坐标转换成屏幕上的二维坐标
       * @param THREE.Vector3 vector three.js三维坐标
       * @return {x:int,y:int} 屏幕坐标
       */
      function transToScreenCoord(vector) {
          var screenCoord = {};
          vector.project(camera);
          console.log(vector.x, vector.y)
          screenCoord.x = (0.5 + vector.x / 2) * window.innerWidth; 
          screenCoord.y = (0.5 - vector.y / 2) * window.innerHeight;
          return screenCoord;
      }

      // 销毁
      function onDestroy() {
        console.log("onDestroy");
        isDestroy = true;
        clearInterval(animateTimerId);
        // clearInterval(mockInsertTimer);
        window.removeEventListener("resize", onWindowResize);
      }

      this.insertPerson = insertPerson;
      this.onDestroy = onDestroy;
    }
  }
};
</script>//http://www.17sucai.com/pins/demo-show?id=26503
